﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace HB.Expand
{
    public static class String2Hash
    {
        /// <summary>
        /// 计算hash值
        /// </summary>
        /// <param name="hash"></param>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        internal static string ToHash(HashAlgorithm hash, string str, Encoding encoding = null)
        {
            if (encoding == null) { encoding = Encoding.UTF8; }
            using (SHA1 sha1 = new SHA1CryptoServiceProvider())
            {
                return hash.ComputeHash(encoding.GetBytes(str)).ToStringByHashBytes();
            }
        }
        /// <summary>
        /// 计算hash值
        /// </summary>
        /// <param name="hash"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        internal static string ToHash(HashAlgorithm hash, Stream stream)
        {
            return hash.ComputeHash(stream).ToStringByHashBytes();
        }

        /// <summary>
        /// 计算文件的hash值
        /// </summary>
        /// <param name="hash"></param>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        internal static string ToHashFromFilePath(HashAlgorithm hash, string FilePath)
        {
            if (!File.Exists(FilePath))
            {
                throw new Exception(string.Format("<{0}>, 不存在", FilePath));
            }

            using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                return ToHash(hash, fs);
            }


        }
        /// <summary>
        /// 使用utf8编码计算
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        public static string ToBase64(this string str, Encoding encoding = null)
        {
            if (str == null) { throw new Exception("输入不能为null"); }
            if (encoding == null) { encoding = Encoding.UTF8; }
            return Convert.ToBase64String(encoding.GetBytes(str));
        }
        /// <summary>
        /// 从base64转为原始字节数组
        /// </summary>
        /// <param name="base64str"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static bool GetBytesFromBase64(this string base64str, out byte[] data)
        {
            data = null;
            bool result = false;
            if (base64str == null) { return false; }
            try
            {
                data = Convert.FromBase64String(base64str);
                result = true;
            }
            catch (Exception ex) { }
            return result;
        }
        /// <summary>
        /// 计算字符串的md5值
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        public static string ToMD5(this string str, Encoding encoding = null)
        {
            using (var hash = new MD5CryptoServiceProvider())
            {
                return ToHash(hash, str, encoding);
            }
        }
        /// <summary>
        /// 计算文件的md5值
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public static string ToMd5FromFilePath(this string FilePath)
        {
            using (var hash = new MD5CryptoServiceProvider())
            {
                return ToHashFromFilePath(hash, FilePath);
            }
        }
        /// <summary>
        /// 计算字符串的SHA1值
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        public static string ToSHA1(this string str, Encoding encoding = null)
        {
            using (var hash = new SHA1CryptoServiceProvider())
            {
                return ToHash(hash, str, encoding);
            }
        }
        /// <summary>
        /// 计算文件的SHA1值
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public static string ToSHA1FromFilePath(this string FilePath)
        {
            using (var hash = new SHA1CryptoServiceProvider())
            {
                return ToHashFromFilePath(hash, FilePath);
            }
        }
        /// <summary>
        /// 计算字符串的SHA256值
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        public static string ToSHA256(this string str, Encoding encoding = null)
        {
            using (var hash = new SHA256CryptoServiceProvider())
            {
                return ToHash(hash, str, encoding);
            }
        }
        /// <summary>
        /// 计算文件的SHA256值
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public static string ToSHA256FromFilePath(this string FilePath)
        {
            using (var hash = new SHA256CryptoServiceProvider())
            {
                return ToHashFromFilePath(hash, FilePath);
            }
        }
        /// <summary>
        /// 计算字符串的SHA384值
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        public static string ToSHA384(this string str, Encoding encoding = null)
        {
            using (var hash = new SHA384CryptoServiceProvider())
            {
                return ToHash(hash, str, encoding);
            }
        }
        /// <summary>
        /// 计算文件的SHA384值
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public static string ToSHA384FromFilePath(this string FilePath)
        {
            using (var hash = new SHA384CryptoServiceProvider())
            {
                return ToHashFromFilePath(hash, FilePath);
            }
        }
        /// <summary>
        /// 计算字符串的SHA512值
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">default=utf-8</param>
        /// <returns></returns>
        public static string ToSHA512(this string str, Encoding encoding = null)
        {
            using (var hash = new SHA512CryptoServiceProvider())
            {
                return ToHash(hash, str, encoding);
            }
        }
        /// <summary>
        /// 计算文件的SHA512值
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public static string ToSHA512FromFilePath(this string FilePath)
        {
            using (var hash = new SHA512CryptoServiceProvider())
            {
                return ToHashFromFilePath(hash, FilePath);
            }
        }
        /// <summary>
        /// 将utf8字符串url编码       
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string ToUrlEncode(this string url)
        {
            StringBuilder sb = new StringBuilder();
            byte[] byStr = System.Text.Encoding.UTF8.GetBytes(url);
            //默认是System.Text.Encoding.Default.GetBytes(str)
            for (int i = 0; i < byStr.Length; i++)
            {
                sb.Append(@"%" + Convert.ToString(byStr[i], 16));
            }
            return sb.ToString();
        }
    }
}
